"""
甘五双拼，以自然码为基础，将声母合并为 21 个，独立出 5 个扩展选重键的双拼方案
"""

from typing import Optional, Final

from dict import *
from aux_code import *
from pinyins import *
from unipy import Unipy

_singleDict8105: Optional[RimeDict] = None
_singleDictExt: Optional[RimeDict] = None
_singleDictName: Final[str] = 'gjwu'

_version = '2404.1'
_temp_dir = '../out/gjwu'
# 注意在 Windows 上不能使用 aux.xxx 作为文件名，它表示设备文件。所有的保留文件名有:
# CON, PRN, AUX, NUL, COM[1-9], LPT[1-9]
_aux_file = '../out/gjwu_aux.txt'


def build():
    print('甘五方案')
    empty_dir(_temp_dir)
    _load_single_dict()
    _make_single_pinyin()
    _make_phrase_pinyin_base()
    compose_aux('../data/base/stroke5.txt', '../data/base/wubi86.txt', _aux_file,
                {'1': 'e', '2': 'i', '3': 'u', '4': 'o', '5': 'a'})
    unipy = Unipy(_aux_file, pinyin_conf='gjwu')
    unipy.writeTableDict(_singleDictName)
    _append_word()
    _write_schema()
    _bundle()


def _load_single_dict():
    global _singleDict8105
    global _singleDictExt
    _singleDict8105 = RimeDict(SINGLE_PINYIN_8105_SRC)
    _singleDictExt = RimeDict(SINGLE_PINYIN_EXT_SRC)
    _singleDict8105.load(skip_head=True)
    _singleDictExt.load(skip_head=True)


def _make_single_pinyin():
    global _singleDict8105
    global _singleDictExt
    if is_file_exists(DICT_PINYIN_SINGLE_LITE):
        return

    out = create_utf8_file(DICT_PINYIN_SINGLE_LITE)
    out.write('# 简体中文单字拼音词库-精简版\n')
    out.write('# 未知读音用 X 表示\n')
    with open_file_as_utf8(SINGLE_LITE_SET) as f:
        for line in f:
            if line.startswith('#'):
                continue
            segments = line.split('\t')
            text = segments[0].strip()
            if _singleDict8105.hasText(text):
                for item in _singleDict8105.items:
                    if item.text == text:
                        out.write('{}\n'.format(item))
            elif _singleDictExt.hasText(text):
                for item in _singleDictExt.items:
                    if item.text == text:
                        out.write('{}\n'.format(item))
            else:
                print('{} not found!'.format(text))
                out.write('# {}\t{}\t{}\n'.format(text, 'X', 0))
            out.flush()
    out.close()


def _make_phrase_pinyin_base():
    if is_file_exists(DICT_PINYIN_PHRASE_BASE):
        return

    baseDict = RimeDict(PHRASE_PINYIN_BASE_SRC)
    baseDict.load(skip_head=True)
    items = []
    items.extend(baseDict.items)
    items.sort(key=lambda x: (len(x.text), x.code, -x.weight))
    with create_utf8_file(DICT_PINYIN_PHRASE_BASE) as out:
        for item in items:
            out.write('{}\n'.format(item))
            out.flush()


def _append_word():
    phraseDict = RimeDict(DICT_PINYIN_PHRASE_BASE)
    phraseDict.load()
    auxDict = RimeDict(_aux_file)
    auxDict.load()
    items = []
    for item in phraseDict.items:
        if len(item.text) > 4:
            continue
        items.append(RimeDictItem(item.text, item.code, item.weight))
    items.sort(key=lambda x: (-x.weight, len(x.text), x.code))
    unique = set()
    encoder = Encoder(config='gjwu')
    with open_file_as_utf8_for_append('../out/{}.dict.yaml'.format(_singleDictName)) as f:
        f.write('# 词组\n')
        for item in items:
            length = len(item.text)
            if length == 4:
                continue
            code = ''
            try:
                for c in item.code.split(' '):
                    if length == 2:  # 两字词
                        code += encoder.encode(c)
                    elif length == 3:  # 三字词
                        code += encoder.encode(c)
                    elif length == 4:  # 四字词
                        # code += encoder.encode(c)[0]
                        continue
                if code in unique and len(code) < 6:
                    first = auxDict.getItem(item.text[0]).code[0]
                    last = auxDict.getItem(item.text[-1]).code[0]
                    code = code + first + last
            except (TypeError, AttributeError):
                print('不能处理的词条: {}'.format(item))
                continue
            if code in unique or len(code) < 4:
                continue
            unique.add(code)
            f.write('{}\t{}\t{}\n'.format(item.text, code, item.weight))
            f.flush()


def _write_schema():
    print('写方案文件')
    copy_files('../schema', _temp_dir, includes='gjwu.*\\.schema\\.yaml')
    copy_files('../schema', _temp_dir, includes='rime.lua')
    # copy_files('../doc', _temp_dir, includes='gjwu-甘五.pdf')


def _bundle():
    print('打包')
    copy_files('../out', _temp_dir, includes='gjwu.*\\.yaml')
    bundle('../out/gjwu', '../out/gjwu-{}'.format(_version))
